# -*- coding: utf-8 -*-
import hashlib
import json
from datetime import datetime
from common.withdraw import db as withdraw_db
import requests
from django.conf import settings

from common.bankcard.model import BANK_DCT
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.tz import local_now
from common.withdraw.model import WITHDRAW_ORDER_STATUS

_LOGGER = track_logging.getLogger('withdraw')

APP_CONF = {
    '18': {
        'API_KEY': 'HroEd76AsuFfX3FTV5PbtNnh97tRIM47dDRD',
        'GATEWAY': 'http://cz.627pay.com/api/pay',
        'QUERY_GATEWAY': 'http://cz.627pay.com/api/query_pay',
    },
}


def _get_api_key(app_id):
    return APP_CONF[app_id]['API_KEY']


def _get_gateway(app_id):
    return APP_CONF[app_id]['GATEWAY']


def _get_query_gateway(app_id):
    return APP_CONF[app_id]['QUERY_GATEWAY']


def generate_sign(parameter, key):
    s = ''
    for k in sorted(parameter.keys()):
        s += '%s=%s&' % (k, parameter[k])
    s += 'apiKey=%s' % key
    _LOGGER.info("kyjhpay sign string is: %s", s)
    m = hashlib.md5()
    m.update(s.encode('utf-8'))
    sign = m.hexdigest().upper()
    return sign


def _verify_notify_sign(data):
    sign = data['Sign']
    data.pop('Sign')
    calculated_sign = generate_sign(data, _get_api_key(data['MerchantNo']))
    if sign != calculated_sign:
        _LOGGER.info("kyjhpay withdraw sign: %s, calculated sign: %s", sign, calculated_sign)
        raise err.ParamError('kyjhpay sign not pass, data: %s' % data)


def create_order(order, channel):
    ''' 快一聚合代付下单 '''
    app_id = channel.appid
    params = {
        "MerchantNo": app_id,
        "OrderPrice": '%.2f' % float(order.amount),
        "OutOrderNo": str(order.id),
        "TradeTime": local_now().strftime('%Y-%m-%d %H:%M:%S'),
        'UserType': '1',
        "AccountNo": order.pay_account_num,
        "AccountName": order.pay_account_username,
        'BankNo': BANK_DCT[order.pay_account_bank],
        "ApiNotifyUrl": settings.KYJHPAY_WITHDRAW_NOTIFY_URL + str(order.id),
    }

    params['Sign'] = generate_sign(params, _get_api_key(app_id))
    _LOGGER.info('kyjhpay data: %s', json.dumps(params))
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}

    # 先设置为未知状态，卡住人工核实
    order.status = WITHDRAW_ORDER_STATUS.THIRD_UNKNOWN
    order.third_type = channel.id
    order.save()

    response = requests.post(_get_gateway(app_id), data=params, timeout=3, headers=headers, verify=False)
    _LOGGER.info("kyjhpay rsp data: %s %s", response.status_code, response.text)
    data = json.loads(response.text)

    if data['resultCode'] == '0000':
        order.status = WITHDRAW_ORDER_STATUS.THIRD
        order.extra_info = response.text
        order.save()
        return True
    else:
        order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        order.extra_info = response.text
        order.save()
        return False


def check_bankcard_withdraw_notify(request, order):
    ''' 快一聚合代付回调 '''
    req_dct = request.GET.dict()
    m_order = withdraw_db.get_order(int(order))
    _LOGGER.info('kyjhpay bankcard callback, notify_data : %s ', req_dct)
    _LOGGER.info('kyjhpay bankcard callback, MerchantNo : %s ', req_dct['MerchantNo'])
    _verify_notify_sign(req_dct)
    order_id = req_dct['OutTradeNo']
    _LOGGER.info('kyjhpay bankcard callback, order_id : %s ', order_id)
    trade_status = req_dct['TradeStatus']
    _LOGGER.info('kyjhpay bankcard callback, trade_status : %s ', trade_status)
    if not m_order:
        raise err.ParamError('kyjhpay bankcard withdraw event does not contain valid order ID')

    if trade_status == 'SUCCESS':
        _LOGGER.info('kyjhpay success: %s %s', req_dct, order_id)
        m_order.status = WITHDRAW_ORDER_STATUS.DONE
        m_order.extra_info = json.dumps(req_dct)
        m_order.third_notify_at = datetime.utcnow()

        m_order.save()
        return True
    elif trade_status == 'FAILED':
        _LOGGER.info('kyjhpay fail: %s %s', req_dct, order_id)
        m_order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        m_order.extra_info = json.dumps(req_dct)
        m_order.third_notify_at = datetime.utcnow()

        m_order.save()
        return False
    else:
        raise err.ParamError('kyjhpay status invalid')


def query_order(order, channel):
    try:
        app_id = channel.appid
        url = _get_query_gateway(app_id)

        request_data = {
            'MerchantNo': app_id,
            'OutTradeNo': str(order.id)
        }

        request_data['Sign'] = generate_sign(request_data, _get_api_key(app_id))

        header = {'Content-Type': 'application/x-www-form-urlencoded'}
        response = requests.post(url, data=request_data, timeout=3, headers=header, verify=False)
        _LOGGER.info("kyjhpay Query withdraw : %s,  data: %s, order_id: %s, request_data: %s" % (
            url, response.text, str(order.id), request_data))

        rsp_data = json.loads(response.text)
        code = rsp_data['resultCode']
        _LOGGER.info('rsp_data[resultCode]%s' % rsp_data['resultCode'])
        if code == '0000':
            status = str(rsp_data['data']['order_status'])
            if status == 'SUCCESS':
                order.status = WITHDRAW_ORDER_STATUS.DONE
            elif status == 'FAILED':
                order.status = WITHDRAW_ORDER_STATUS.REJECTED
            elif status == 'WAITING_PAYMENT':
                order.status = WITHDRAW_ORDER_STATUS.WAIT
            order.extra_info = json.dumps(rsp_data['msg'])
            order.save()
        else:
            order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
            order.extra_info = response.text
            order.save()

    except Exception, e:
        _LOGGER.info('kyjhpay Query withdraw fail: %s, %s', e, order.id)
        return False
